package butines.game.lastcolony.entities;

import static butines.game.lastcolony.entities.EntityAction.CLOSE;
import static butines.game.lastcolony.entities.EntityAction.CONTRUCTING;
import static butines.game.lastcolony.entities.EntityAction.DEPLOY;
import static butines.game.lastcolony.entities.EntityAction.GUARD;
import static butines.game.lastcolony.entities.EntityAction.OPEN;
import static butines.game.lastcolony.entities.EntityAction.STAND;
import static butines.game.lastcolony.entities.EntityAction.TELEPORT;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;

import butines.core.GameImage;


public class Building extends Entity {
    
    public static final EntityClass BASE;
    public static final EntityClass STARPORT;
    public static final EntityClass HARVESTER;
    public static final EntityClass GROUND_TURRET;
    
    static {
        BASE = new EntityClass();
        BASE.setName("Base");
        BASE.setPixelWidth(60);
        BASE.setPixelHeight(60);
        BASE.setBaseWidth(40);
        BASE.setBaseHeight(40);
        BASE.setPixelOffsetX(0);
        BASE.setPixelOffsetY(20);
        BASE.setBuildableGrid(new int[][] {
            {1,1},
            {1,1},
        });
        BASE.setPassableGrid(new int[][] {
            {1,1},
            {1,1},
        });
        BASE.setSight(3);
        BASE.setHitPoints(500);
        BASE.setCost(5000);
        BASE.setSpriteSheet(new GameImage("images/buildings/base.png"));
        BASE.addEntitySprite("healthy", 4);
        BASE.addEntitySprite("damaged", 1);
        BASE.addEntitySprite("contructing", 3);
        BASE.setSelectable(true);
        BASE.setOrdersType(EntityOrders.Type.STAND);
        BASE.setAction(EntityAction.STAND);
        
        STARPORT = new EntityClass();
        STARPORT.setName("Startport");
        STARPORT.setPixelWidth(40);
        STARPORT.setPixelHeight(60);
        STARPORT.setBaseWidth(40);
        STARPORT.setBaseHeight(55);
        STARPORT.setPixelOffsetX(1);
        STARPORT.setPixelOffsetY(5);
        STARPORT.setBuildableGrid(new int[][] {
            {1,1},
            {1,1},
            {1,1},
        });
        STARPORT.setPassableGrid(new int[][] {
            {1,1},
            {0,0},
            {0,0},
        });
        STARPORT.setSight(3);
        STARPORT.setCost(2000);
        STARPORT.setHitPoints(300);
        STARPORT.setSpriteSheet(new GameImage("images/buildings/starport.png"));
        STARPORT.addEntitySprite("teleport", 9);
        STARPORT.addEntitySprite("closing", 18);
        STARPORT.addEntitySprite("healthy", 4);
        STARPORT.addEntitySprite("deamage", 1);
        STARPORT.setSelectable(true);
        STARPORT.setOrdersType(EntityOrders.Type.STAND);
        STARPORT.setAction(EntityAction.STAND);
        
        
        HARVESTER = new EntityClass();
        HARVESTER.setName("Harvester");
        HARVESTER.setPixelWidth(40);
        HARVESTER.setPixelHeight(60);
        HARVESTER.setBaseWidth(40);
        HARVESTER.setBaseHeight(20);
        HARVESTER.setPixelOffsetX(-2);
        HARVESTER.setPixelOffsetY(40);
        HARVESTER.setBuildableGrid(new int[][] {
            {1,1}
        });
        HARVESTER.setPassableGrid(new int[][] {
            {1,1}
        });
        HARVESTER.setSight(3);
        HARVESTER.setCost(5000);
        HARVESTER.setHitPoints(300);
        HARVESTER.setSpriteSheet(new GameImage("images/buildings/harvester.png"));
        HARVESTER.addEntitySprite("deploy", 17);
        HARVESTER.addEntitySprite("healthy", 3);
        HARVESTER.addEntitySprite("demaged", 1);
        HARVESTER.setSelectable(true);
        HARVESTER.setOrdersType(EntityOrders.Type.STAND);
        HARVESTER.setAction(EntityAction.STAND);
        

        GROUND_TURRET = new EntityClass();
        GROUND_TURRET.setName("Ground turret");
        GROUND_TURRET.setCanAttack(true);
        GROUND_TURRET.setCanAttackLand(true);
        GROUND_TURRET.setCanAttackAir(false);
        GROUND_TURRET.setWeaponType(WeaponType.CANNON_BALL);
        GROUND_TURRET.setAction(EntityAction.GUARD);
        GROUND_TURRET.setDirection(0);
        GROUND_TURRET.setDirections(8);
        GROUND_TURRET.setOrdersType(EntityOrders.Type.GUARD);
        GROUND_TURRET.setPixelWidth(38);
        GROUND_TURRET.setPixelHeight(32);
        GROUND_TURRET.setBaseWidth(20);
        GROUND_TURRET.setBaseHeight(18);
        GROUND_TURRET.setPixelOffsetX(9);
        GROUND_TURRET.setPixelOffsetY(12);
        GROUND_TURRET.setBuildableGrid(new int[][] {
            {1,1}
        });
        GROUND_TURRET.setPassableGrid(new int[][] {
            {1,1}
        });
        GROUND_TURRET.setSight(3);
        GROUND_TURRET.setCost(1500);
        GROUND_TURRET.setHitPoints(200);
        GROUND_TURRET.setSpriteSheet(new GameImage("images/buildings/ground-turret.png"));
        GROUND_TURRET.addEntitySprite("teleport", 9);
        GROUND_TURRET.addEntitySprite("healthy", 1, 8);
        GROUND_TURRET.addEntitySprite("demaged", 1);
        GROUND_TURRET.setSelectable(true);
        GROUND_TURRET.setAction(EntityAction.GUARD);
    }
    

    public static Building create(String name, Object ... values) {
        if ("base".equals(name)) {
            return BASE.create(Building.class, values);
        } else if ("starport".equals(name)) {
            return STARPORT.create(Building.class, values);
        } else if ("harvester".equals(name)) {
            return HARVESTER.create(Building.class, values);
        } else if ("ground-turret".equals(name)) {
            return GROUND_TURRET.create(Building.class, values);
        }
        return null;
    }
    
    private int imageOffset;
    private int animationIndex;
    private EntitySprite imageList;
    
    public Building() {

    }
    
    private void drawLifeBar(Graphics2D g2d, float drawingX, float drawingY) {
        int x = (int) (drawingX + getPixelOffsetX());
        int y = (int) (drawingY - 2 * game.getLifeBarHeight());
        int w = getBaseWidth();
        int h = game.getLifeBarHeight();

        Color healthColor = isHealthy() ? game.getHealthBarHealthyFillColor() : game.getHealthBarDamagedFillColor();

        g2d.setColor(healthColor);
        g2d.fillRect(x, y, (int) (w * getLife() / (float) getHitPoints()), h);

        g2d.setColor(game.getHealthBarBorderColor());
        g2d.drawRect(x, y, w, h);
    }
    
    private void drawSelection(Graphics2D g2d, float drawingX, float drawingY) {
        int x = (int) (drawingX + getPixelOffsetX());
        int y = (int) (drawingY + getPixelOffsetY());

        g2d.setColor(game.getSelectionFillColor());
        g2d.fillRect(x - 1, y - 1, getBaseWidth() + 2, getBaseHeight() + 2);

        g2d.setColor(game.getSelectionBorderColor());
        g2d.drawRect(x - 1, y - 1, getBaseWidth() + 2, getBaseHeight() + 2);
    }
    
    public void draw(Graphics2D g2d) {
        float sx = (getX() * getGame().getGridSize()) - getGame().getOffsetX() - getPixelOffsetX();
        float sy = (getY() * getGame().getGridSize()) - getGame().getOffsetY() - getPixelOffsetY();

        // All sprite sheets will have blue in the first row and green in the second row
        int colorIndex = (getTeam() == EntityTeam.BLUE) ? 0 : 1;// getTeam().ordinal();
        int colorOffset = colorIndex * getEntityClass().getPixelHeight();

        int ix = imageOffset * getEntityClass().getPixelWidth();
        int iy = colorOffset;
        int iw = getEntityClass().getPixelWidth();
        int ih = getEntityClass().getPixelHeight();

        if (isSelected()) {
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            drawSelection(g2d, sx, sy);
            drawLifeBar(g2d, sx, sy);
        }
        
        getEntityClass().getSpriteSheet().draw(g2d, (int) sx, (int) sy, ix, iy, iw, ih);
  
        
//        g2d.setColor(Color.WHITE);
//        g2d.drawString("[" + getX() + "," + getY() + "]", sx+ getPixelOffsetX(), sy+ getPixelOffsetY());
        
//        g2d.setColor(Color.RED);
//        g2d.drawRect(sx + getPixelOffsetX(), sy + getPixelOffsetY(), getBaseWidth(), getBaseHeight());
        
    }

    public void animate() {
        // Consider an item healthy if it has more than 40% life
        if (getLife() > getEntityClass().getHitPoints() * 0.4) {
            setLifeCode("healthy");
        } else if (getLife() <= 0) {
            setLifeCode("dead");
            getGame().remove(this);
            return;
        } else {
            setLifeCode("damaged");
        }

        if (getAction() == STAND) {
            imageList = getEntityClass().getEntitySprite(getLifeCode());
            imageOffset = imageList.getOffset() + animationIndex;
            animationIndex++;
            if (animationIndex >= imageList.getCount()) {
                animationIndex = 0;
            }
        }

        if (getAction() == CONTRUCTING) {
            imageList = getEntityClass().getEntitySprite("contructing");
            imageOffset = imageList.getOffset() + animationIndex;
            animationIndex++;
            // Once constructing is complete go back to standing
            if (animationIndex >= imageList.getCount()) {
                animationIndex = 0;
                setAction(STAND);
            }
        }
        
        if (getAction() == TELEPORT) {
            imageList = getEntityClass().getEntitySprite("teleport");
            imageOffset = imageList.getOffset() + animationIndex;
            animationIndex++;
            // Once teleporting is complete, move to either guard or stand mode
            if (animationIndex >= imageList.getCount()) {
                animationIndex = 0;
                if (getEntityClass().isCanAttack()) {
                    setAction(EntityAction.GUARD);
                } else {
                    setAction(EntityAction.STAND);
                }
            }
        }
        
        if (getAction() == CLOSE) {
            imageList = getEntityClass().getEntitySprite("closing");
            imageOffset = imageList.getOffset() + animationIndex;
            animationIndex++;
            // Once closing is complete go back to standing
            if (animationIndex >= imageList.getCount()) {
                animationIndex = 0;
                setAction(EntityAction.STAND);
            }
        }
        
        if (getAction() == OPEN) {
            imageList = getEntityClass().getEntitySprite("closing");
            imageOffset = imageList.getOffset() + imageList.getCount() - this.animationIndex;
            animationIndex++;
            // Once opening is complete, go back to close
            if (this.animationIndex >= this.imageList.getCount()) {
                animationIndex = 0;
                setAction(CLOSE);
            }
        }
        
        if (getAction() == DEPLOY) {
            imageList = getEntityClass().getEntitySprite("deploy");
            imageOffset = imageList.getOffset() + this.animationIndex;
            animationIndex++;
            // Once deploying is complete, go back to stand
            if (animationIndex >= imageList.getCount()){
                animationIndex = 0;
                setAction(STAND);
            }
        }
        
        if (getAction() == GUARD) {
            if ("damaged".equals(getLifeCode())){
                // The damaged turret has no directions
                imageList = getEntityClass().getEntitySprite(getLifeCode());
            } else {
                // The healthy turret has 8 directions
                imageList = getEntityClass().getEntitySprite(getLifeCode() + '-' + (int) getDirection());
            }
            imageOffset = imageList.getOffset();
        }
        
    }

    public void processOrders() {
        
    }
    
}
